<?php

namespace App\Service\OpenShop\Feishu;

use App\Console\Commands\OpenShop\SkipStepMultiple;
use App\Enums\BaseErrorCode;
use App\Enums\Check\CheckEnum;
use App\Enums\OpenShop\InvestmentPromotion\MainProcessEnum;
use App\Enums\OpenShop\InvestmentPromotion\SignOrderEnum;
use App\Enums\OpenShop\InvestmentPromotion\SiteMissionEnum;
use App\Enums\OpenShop\InvestmentPromotion\SpaceDesignErrorTrait;
use App\Enums\OpenShop\InvestmentPromotion\UploadFileResourceEnum;
use App\Enums\OpenShop\MissionTemplateEnum;
use App\Events\OpenShop\OpenShopProcessEvent;
use App\Events\OpenShop\SignSiteMissionEvent;
use App\Exceptions\Custom\ResponseHttpException;
use App\Http\Middleware\OpenShop\UserPermissionAuth;
use App\Library\FeiShu\SendFs;
use App\Models\Appraise\AppraiseModel;
use App\Models\College\CollegeTrainingOrderLogModel;
use App\Models\College\CollegeTrainingOrderModel;
use App\Models\Cruise\CruiseTemplateModel;
use App\Models\OpenShop\Common\OpenShopOrderManagerModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopLogisticsInformationModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopPreparationOrderRefundModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderLogModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderPayHistoryModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSiteMissionModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSpaceDesignCostMappingModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSpaceDesignModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSpaceDesignSoftLogisticsModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSpaceDesignSoftOutfitMappingModel as SoftOutfitModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopUploadFileResourceModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopUserContractModel;
use App\Models\OpenShop\ShopEngineeringConstruction\OpenShopEngineeringConstructionModel;
use App\Models\OpenShop\SiteLocation\OpenShopSiteLocationModel;
use App\Models\System\SystemNotifyCenterModel;
use App\Remote\Orm\OrmNewOrderRemote;
use App\Remote\Orm\OrmShopRemote;
use App\Service\College\CollegeTrainingOrderService;
use App\Service\Common\FsCardService;
use App\Service\OpenShop\Import\HistoryOrder\HistoryOrderExecute;
use App\Service\OpenShop\Import\HistoryOrder\HistoryOrderParam;
use App\Service\OpenShop\OrderService;
use App\Service\OpenShop\User\RmsUserService;
use App\Service\System\SystemNotifyService;
use App\Service\WorkOrder\Appraise\NotifyService;
use App\Support\ChangeSupport;
use Exception;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Kuafu\File\FileUtil;

class SpaceDesignService extends \App\Service\BaseService
{

    public static function insertSpaceDesignData($mainData)
    {
        try {
            //添加主表数据
            OpenShopSpaceDesignModel::query()
                                    ->insert($mainData);
        } catch (Exception $exception) {
            handleException($exception, BaseErrorCode::$INSERT_SPACE_DESIGN_ERR);
        }
    }


    public static function handleSoftData($orderNo)
    {
        $imgList = self::getImgList($orderNo);
        if (!empty($imgList)) {
            $softInfo                 = SoftOutfitModel::query()
                                                       ->where('orderNo', $orderNo)
                                                       ->first();
            $imgList['softOutfitFee'] = $softInfo['fee'] ?? 0;
            $imgList['softId']        = $softInfo['id'] ?? 0;

            if (($softInfo['fileId'] ?? 0) == 0) {
                $imgList['softOutfitFee'] = 0;
            }
        }

        return $imgList;
    }

    public static function getImgList($orderNo)
    {
        $position = UploadFileResourceEnum::SPACE_DESIGN_POSITION_LIST;
        $fileList = UploadFileResourceService::getFileListByPosition($orderNo, $position);
        if (empty($fileList->toArray())) {
            return null;
        } else {
            return UploadFileResourceEnum::handleFileRes($fileList,
                UploadFileResourceEnum::SPACE_DESIGN_DATABASE_LIST);
        }
    }

    public static function getMainInfo($orderNo)
    {
        //查询主表信息
        $designInfo = OpenShopSpaceDesignModel::query()
                                              ->with([
                                                  'costMappingRel' => function ($query) {
                                                      $query->orderBy('id')->limit(1);
                                                  }
                                              ])
                                              ->where(['orderNo' => $orderNo])
                                              ->where('isDeleted', 0)
                                              ->first();
        if (!$designInfo) {
            return null;
        }
        $designInfo                = $designInfo->toArray();
        $designInfo['costMapping'] = $designInfo['cost_mapping_rel'][0] ?? [];
        unset($designInfo['cost_mapping_rel']);
        return $designInfo;
    }

    public static function getSpaceDesignMapping($orderNo)
    {
        //查询主表信息
        $designInfo = OpenShopSpaceDesignModel::query()
                                              ->with([
                                                  'costMappingRel' => function ($query) {
                                                      $query->where('isDeleted', 0)
                                                            ->orderBy('orderStatus');
                                                  }
                                              ])
                                              ->with([
                                                  'softMappingRel' => function ($query) {
                                                      $query->where('isDeleted', 0)
                                                            ->orderBy('orderStatus');
                                                  }
                                              ])
                                              ->where(['orderNo' => $orderNo])
                                              ->where('isDeleted', 0)
                                              ->first();
        if (!$designInfo) {
            return null;
        }
        $designInfo                = $designInfo->toArray();
        $designInfo['costMapping'] = $designInfo['cost_mapping_rel'];

        // 老软装tab - 过滤掉新软装订单
        $designInfo['softMapping'] = collect($designInfo['soft_mapping_rel'])
            ->filter(function ($item) {
            if ($item['fileId'] == 0) {
                return false;
            }

            return true;
        })->filter()->values()->toArray();
        if (!empty($designInfo['costMapping'])) {
            $uidList      = array_unique(array_column($designInfo['costMapping'], 'createdByUid'));
            $userInfoList = RmsUserService::getRmsUserInfoByUserIds($uidList);
            $userInfoList = array_column($userInfoList['data'] ?? [], null, 'id');
            foreach ($designInfo['costMapping'] as $key => &$value) {
                if (isset($userInfoList[$value['createdByUid']])) {
                    $value['createdByName'] = $userInfoList[$value['createdByUid']]['username'];
                }
            }
        }
        unset($designInfo['cost_mapping_rel']);
        unset($designInfo['soft_mapping_rel']);

        $nowStepStatus = (int)OpenShopMainProcessModel::query()->where('orderNo', $orderNo)->value('nowStepStatus');

        // 跳过设计流程
        $designInfo['skipDesignBtn'] = (int)in_array($nowStepStatus,
            [MissionTemplateEnum::STEP_STATUS_13, MissionTemplateEnum::STEP_STATUS_14]);

        // 跳过设备模块
        $designInfo['skipEquipmentBtn'] = (int)in_array($nowStepStatus,
            [MissionTemplateEnum::STEP_STATUS_15, MissionTemplateEnum::STEP_STATUS_16]);

        // 跳过软装模块
        $designInfo['skipSoftBtn'] = (int)in_array($nowStepStatus,
            [MissionTemplateEnum::STEP_STATUS_8, MissionTemplateEnum::STEP_STATUS_17]);

        return $designInfo;
    }


    public static function preparationConfirm(
        string $orderNo,
        int $preparationUid,
        string $preparationName,
        $receiverName = '',
        $phoneNumber = '',
        $regions = [],
        $addressDetail = ''
    ) {
        try {
            $data = [
                'preparationUid'  => $preparationUid,
                'preparationName' => $preparationName,
                'updatedByUid'    => $preparationUid,
                'step'            => MainProcessEnum::SPACE_DESIGN_STEP_NEXT_STEP[MainProcessEnum::SPACE_DESIGN_STEP_TYPE_CONFIRM_SHOP_INFO],
            ];
            OpenShopSpaceDesignModel::setData($orderNo, $data);
            //修改任务状态
            event(new SignSiteMissionEvent($orderNo, MissionTemplateEnum::STEP_STATUS_6, $preparationUid));
            $processAndAuthUser = self::getMainProcessAndAuthUser($orderNo);
            OpenShopOrderManagerModel::generateManagerOrUpdate(
                OpenShopOrderManagerModel::MANAGER_TYPE_4,
                $processAndAuthUser['order']->mainProcessId,
                $preparationUid,
                $preparationName
            );
            event(new OpenShopProcessEvent($processAndAuthUser['rmsUser']->id,
                $processAndAuthUser['order']->mainProcessId, MainProcessEnum::MAIN_PROCESS_SPACE_DESIGN,
                MainProcessEnum::SPACE_DESIGN_STEP_TYPE_CONFIRM_SHOP_INFO));

            //订货门店建档
            //获取门店名称
            $notice   = new NoticeService($orderNo);
            $shopName = $notice->getShopName();
            //根据订单号获得门店基础信息
            $siteLocationModel = OpenShopSiteLocationModel::query()
                                                          ->where('orderNo', $orderNo)->whereIn('source',
                    [
                        OpenShopSiteLocationModel::SOURCE_OPEN_SHOP,
                        OpenShopSiteLocationModel::SOURCE_HOUSING
                    ])
                                                          ->with([
                                                              'baseUserInfoRel',
                                                              'identityCardRel',
                                                              'signOrderRel',
                                                              'openShopMainProcessRel'
                                                          ])
                                                          ->first()
                                                          ->toArray();

            $mainProcessModel = OpenShopMainProcessModel::query()->where('orderNo', $orderNo)->first();
            if ($mainProcessModel->childLocationOrder == 0) {
                if (mb_strlen($receiverName)) {
                    //开店镜像
                    OpenShopLogisticsInformationModel::query()->create([
                        'orderNo'       => $orderNo,
                        'receiverName'  => $receiverName,
                        'phoneNumber'   => $phoneNumber,
                        'regions'       => $regions['addressPrefix'] ?? '',
                        'provinceCode'  => $regions['provinceCode'] ?? 0,
                        'cityCode'      => $regions['cityCode'] ?? 0,
                        'areaCode'      => $regions['districtCode'] ?? 0,
                        'addressDetail' => $addressDetail,
                    ]);
                    //物流建档
                    OrmShopRemote::createStore($shopName,
                        $phoneNumber,
                        $receiverName,
                        $siteLocationModel['sign_order_rel']['shopCode'] ?? '',
                        $siteLocationModel['areaCode'] ?? 0,
                        $addressDetail,
                        $siteLocationModel['open_shop_main_process_rel']['shopId'] ?? '',
                        $regions['addressPrefix'] ?? ''
                    );
                } else {
                    OrmShopRemote::createStore($shopName,
                        $siteLocationModel['base_user_info_rel']['mobile'] ?? '',
                        $siteLocationModel['identity_card_rel']['name'] ?? '',
                        $siteLocationModel['sign_order_rel']['shopCode'] ?? '',
                        $siteLocationModel['areaCode'] ?? 0,
                        $siteLocationModel['address'] ?? '',
                        $siteLocationModel['open_shop_main_process_rel']['shopId'] ?? '',
                        $siteLocationModel['cityArea'] ?? ''
                    );
                }
            }

            try {
                // 生成商学院培训流程
                (new CollegeTrainingOrderService(0))->orderAdd(0, $mainProcessModel->shopId, true);

                (new ShopTagsService($orderNo))
//                    ->updateOrderPrepareTag() // 生成筹备正常标签 往前移动一个步骤
                    ->updateSchoolTag(); // 生成商学院培训标签

            } catch (\Exception $e) {
                Log::warning($e);
            }

        } catch (Exception $exception) {
            handleException($exception, BaseErrorCode::$SET_PREPARATION_CONFIRM_ERR);
        }
    }

    public static function assignSpaceDesign($orderNo, $designUid, $designName, $updatedByUid)
    {
        try {
            $data = [
                'designUid'    => $designUid,
                'designName'   => $designName,
                'updatedByUid' => $updatedByUid,
                'step'         => MainProcessEnum::SPACE_DESIGN_STEP_NEXT_STEP[MainProcessEnum::SPACE_DESIGN_STEP_TYPE_SPACE_DESIGN_ASSIGN_WAIT],
            ];
            OpenShopSpaceDesignModel::setData($orderNo, $data);
            $processAndAuthUser = self::getMainProcessAndAuthUser($orderNo);
            OpenShopOrderManagerModel::generateManagerOrUpdate(
                OpenShopOrderManagerModel::MANAGER_TYPE_3,
                $processAndAuthUser['order']->mainProcessId,
                $designUid,
                $designName
            );
            event(new SignSiteMissionEvent($orderNo, MissionTemplateEnum::STEP_STATUS_7, $updatedByUid));
            event(new OpenShopProcessEvent($processAndAuthUser['rmsUser']->id ?? 0,
                $processAndAuthUser['order']->mainProcessId, MainProcessEnum::MAIN_PROCESS_SPACE_DESIGN,
                MainProcessEnum::SPACE_DESIGN_STEP_TYPE_SPACE_DESIGN_ASSIGN_WAIT));
        } catch (Exception $exception) {
            handleException($exception, BaseErrorCode::$SET_SPACE_DESIGN_ERR);
        }
    }


    public static function uploadDesignMappingData(
        $orderNo,
        $planeCad,
        $planePdf,
        $constructionCad,
        $constructionPdf,
        $effectImg,
        array $equipments
    ) {
        $rmsInfo = getRmsUserInfoByAuth();

        if (HistoryOrderParam::$importOrderMode == true) {
            $softOutfitFee = 0;
            $code = '';
        } else {

            // 创建软装订单
            $body = DesignerEquipmentService::createNewOrder($orderNo, $equipments, $rmsInfo->username, CheckEnum::SYS_TYPE_OPEN_SHOP_DECORATE);
            $code = $body['code'] ?? -1;
            if (0 !== $code) {
                $msg = $body['msg'] ?? '创建软装订单失败';
                self::throwErr($msg);
            }
            $softOutfitFee = round( 100 * $body['data']['total_amount']);
        }

        try {
            DB::beginTransaction();
            $mappingData = self::getMappingData($planeCad, $planePdf, $constructionCad, $constructionPdf, $effectImg);
            //查询主流程id
            $orderModel    = OpenShopSignOrderModel::query()
                                                   ->where('orderNo', $orderNo)
                                                   ->first();
            $mainProcessId = $orderModel->mainProcessId;

            array_walk($mappingData, function (&$value, $key) use ($rmsInfo, $orderNo) {
                $value['createdAt']    = time();
                $value['createdByUid'] = $rmsInfo->id;
                $value['updatedAt']    = time();
                $value['updatedByUid'] = $rmsInfo->id;
                $value['orderNo']      = $orderNo;
            });
            OpenShopUploadFileResourceModel::query()
                                           ->insert($mappingData);
            $softData = [
                'orderNo'       => $orderNo,
                'preparationNo' => self::genPreparationNo("CB"),
                'fileId'        => 0,
                'fee'           => $softOutfitFee,
                'createdAt'     => time(),
                'createdByUid'  => $rmsInfo->id,
                'updatedAt'     => time(),
                'updatedByUid'  => $rmsInfo->id,
                'newOrderCode' => $body['data']['code'] ?? '',
            ];
            //添加空间设计软装关联表
            SoftOutfitModel::query()
                           ->insert($softData);
            //修改space状态
            OpenShopSpaceDesignModel::query()
                                    ->where('orderNo', $orderNo)
                                    ->update([
                                        'step' => MainProcessEnum::SPACE_DESIGN_STEP_NEXT_STEP[MainProcessEnum::SPACE_DESIGN_STEP_TYPE_DESIGN_UPLOAD_FILE]
                                    ]);
            //工程营建阶段
            $engineerData = [
                'mainProcessId' => $mainProcessId,
                'orderNo'       => $orderNo,
                'createdAt'     => time()
            ];
            OpenShopEngineeringConstructionModel::query()
                                                ->updateOrCreate([
                                                    'orderNo' => $orderNo
                                                ], [
                                                    'mainProcessId' => $mainProcessId,
                                                    'createdAt'     => time()
                                                ]);
//                                                ->insert($engineerData);
            $rmsInfo = getRmsUserInfoByAuth();
            DB::commit();
            event(new SignSiteMissionEvent($orderNo, MissionTemplateEnum::STEP_STATUS_8, $rmsInfo->id));
            event(new OpenShopProcessEvent($rmsInfo->id, $mainProcessId, MainProcessEnum::MAIN_PROCESS_SPACE_DESIGN,
                MainProcessEnum::SPACE_DESIGN_STEP_TYPE_DESIGN_UPLOAD_FILE));
            (new ShopTagsService($orderNo))->updateSoftPayTag();

        } catch (Exception $exception) {
            DB::rollBack();
            handleException($exception, BaseErrorCode::$UPLOAD_IMG_ERR);
        }

    }

    public static function handleImg($image, $type, $position)
    {
        $data = [];
        foreach ($image as $key => $value) {
            $data[$key]['type']     = $type;
            $data[$key]['url']      = str_replace(FileUtil::domain(), '', $value);
            $data[$key]['url']      = getPrivateFileKey($value);
            $data[$key]['position'] = $position;
        }
        return $data;
    }

    public static function getMainProcessAndAuthUser($orderNo)
    {
        //查询主流程id
        $orderModel = OpenShopSignOrderModel::query()
                                            ->where('orderNo', $orderNo)
                                            ->first();
        $rmsInfo    = getRmsUserInfoByAuth();
        return ['rmsUser' => $rmsInfo, 'order' => $orderModel];
    }

    public static function setDesignMappingData(
        $orderNo,
        $planeCad,
        $planePdf,
        $constructionCad,
        $constructionPdf,
        $effectImg,
        $softOutfitXlsx,
        $softOutfitFee,
        $softId
    ) {
        try {
            DB::beginTransaction();
            $rmsInfo     = $rmsInfo = getRmsUserInfoByAuth();
            $mappingData = self::getMappingData($planeCad, $planePdf, $constructionCad, $constructionPdf, $effectImg,
                []);
            array_walk($mappingData, function (&$value, $key) use ($rmsInfo, $orderNo) {
                $value['createdByUid'] = $rmsInfo->id;
                $value['updatedAt']    = time();
                $value['createdAt']    = time();
                $value['updatedByUid'] = $rmsInfo->id;
                $value['orderNo']      = $orderNo;
            });

            // 获取原来的数据
            $orgList = OpenShopUploadFileResourceModel::query()
                                                      ->where('orderNo', $orderNo)
                                                      ->whereIn('position',
                                                          UploadFileResourceEnum::SPACE_DESIGN_POSITION_LIST)
                                                      ->get()
                                                      ->toArray();

            UploadFileResourceService::updateFileListByPosition($orderNo,
                UploadFileResourceEnum::SPACE_DESIGN_POSITION_LIST, $mappingData,
                OpenShopSignOrderLogModel::UPDATE_SPACE_DESIGN);

            $pmCadChange = self::checkOneDiff($orgList, $mappingData,
                UploadFileResourceEnum::SPACE_DESIGN_CAD_PLANE);
            $pmPdfChange = self::checkOneDiff($orgList, $mappingData,
                UploadFileResourceEnum::SPACE_DESIGN_PDF_PLANE);
            $sgCadChange = self::checkOneDiff($orgList, $mappingData,
                UploadFileResourceEnum::SPACE_DESIGN_CAD_CONSTRUCTION);
            $sgPdfChange = self::checkOneDiff($orgList, $mappingData,
                UploadFileResourceEnum::SPACE_DESIGN_PDF_CONSTRUCTION);
            $xgtChange   = self::checkArrDiff($orgList, $mappingData,
                UploadFileResourceEnum::SPACE_DESIGN_IMG);

            $id = self::getFileId($orderNo);
            //更改软装设计费和关联id
            if (!empty($softId)) {
                $setData = [
                    'fee'          => $softOutfitFee,
                    'fileId'       => $id,
                    'updatedAt'    => time(),
                    'updatedByUid' => $rmsInfo->id
                ];
                ChangeSupport::getInstance()->singleUpdate(
                    new SoftOutfitModel(),
                    function ($query) use ($softId) {
                        $query->where("id", $softId);
                    },
                    $setData,
                    "修改软装价格",
                    SoftOutfitModel::getOrderLogTranslate()
                );


            } else {
                $softData = [
                    'orderNo'       => $orderNo,
                    'preparationNo' => self::genPreparationNo("CB"),
                    'fileId'        => $id,
                    'fee'           => $softOutfitFee,
                    'createdAt'     => time(),
                    'createdByUid'  => $rmsInfo->id,
                    'updatedAt'     => time(),
                    'updatedByUid'  => $rmsInfo->id
                ];
                SoftOutfitModel::query()
                               ->insert($softData);
            }
            //写入订单日志
            ChangeSupport::getInstance()->batchChangesWriteToOrderLog(
                OpenShopSignOrderModel::getOrderIdByOrderNo($orderNo),
                OpenShopSignOrderLogModel::UPDATE_SPACE_DESIGN,
                $rmsInfo->username,
                $rmsInfo->id,
            );
            DB::commit();


            $notice   = new NoticeService($orderNo);
            $shopName = $notice->getShopCode() . $notice->getShopName();
            $notice->setUrl();
            $changeText = '';
            if ($pmCadChange['isChange']) {
                $changeText .= '平面图(CAD) ';
            }
            if ($pmPdfChange['isChange']) {
                $changeText .= '平面图(PDF) ';
            }
            if ($sgCadChange['isChange']) {
                $changeText .= '施工图(CAD) ';
            }
            if ($sgPdfChange['isChange']) {
                $changeText .= '施工图(PDF) ';
            }
            if ($xgtChange['isChange']) {
                $changeText .= '效果图';
            }

            $updateUserName = getRmsUserInfoByAuth()->username;
            $updateTime     = date('Y-m-d H:i:s', time());

            $changeBefore = '';
            $changeAfter  = '';

            $expireAt = 180 * 86400;

            if ($pmCadChange['isChange']) {
                $changeBefore .= '[平面图(CAD)](' . privateFilePath($pmCadChange['org'], $expireAt) . ') ';
                $changeAfter  .= '[平面图(CAD)](' . privateFilePath($pmCadChange['updated'], $expireAt) . ') ';
            }
            if ($pmPdfChange['isChange']) {
                $changeBefore .= '[平面图(PDF)](' . privateFilePath($pmPdfChange['org'], $expireAt) . ') ';
                $changeAfter  .= '[平面图(PDF)](' . privateFilePath($pmPdfChange['updated'], $expireAt) . ') ';
            }
            if ($sgCadChange['isChange']) {
                $changeBefore .= '[施工图(CAD)](' . privateFilePath($sgCadChange['org'], $expireAt) . ') ';
                $changeAfter  .= '[施工图(CAD)](' . privateFilePath($sgCadChange['updated'], $expireAt) . ') ';
            }
            if ($sgPdfChange['isChange']) {
                $changeBefore .= '[施工图(PDF)](' . privateFilePath($sgPdfChange['org'], $expireAt) . ') ';
                $changeAfter  .= '[施工图(PDF)](' . privateFilePath($sgPdfChange['updated'], $expireAt) . ') ';
            }

            if ($xgtChange['isChange']) {
                foreach ($xgtChange['org'] as $key => $img) {
                    $changeBefore .= '[效果图 (' . ($key + 1) . ')](' . privateFilePath($img,
                            $expireAt) . ') ';
                }

                foreach ($xgtChange['updated'] as $key => $img) {
                    $changeAfter .= '[效果图 (' . ($key + 1) . ')](' . privateFilePath($img,
                            $expireAt) . ') ';
                }
            }

            if (!empty($changeText)) {
                $templateJson = vsprintf(file_get_contents(resource_path('OpenShop/feishu/notifyTemplate/designNotify.json')),
                    [
                        $shopName,
                        $orderNo,
                        $changeText,
                        $updateUserName,
                        $updateTime,
                        $changeBefore,
                        $changeAfter,
                        $notice->getUrl(),
                        $shopName,
                    ]);
                SendFs::newRobot(SendFs::ROBOT_DESIGN_NOTIFY)->setCardMessageBody(json_decode($templateJson, 1))
                      ->send();
            }
        } catch (Exception $exception) {
            DB::rollBack();
            handleException($exception);
        }
    }

    public static function checkOneDiff(array $arr1, array $arr2, int $type)
    {
        $coOne1 = collect($arr1)->where('position', $type)->pluck('url')->first();
        $coOne2 = collect($arr2)->where('position', $type)->pluck('url')->first();

        if ($coOne1 != $coOne2) {
            return [
                'org'      => $coOne1,
                'updated'  => $coOne2,
                'isChange' => true
            ];
        } else {
            return [
                'org'      => $coOne1,
                'updated'  => $coOne2,
                'isChange' => false
            ];
        }
    }

    public static function checkArrDiff(array $arr1, array $arr2, int $type)
    {
        $coArr1 = collect($arr1)->where('position', $type)->pluck('url');
        $coArr2 = collect($arr2)->where('position', $type)->pluck('url');

        if ($coArr2->diff($coArr1)->count() || $coArr1->diff($coArr2)->count()) {
            return [
                'org'      => $coArr1,
                'updated'  => $coArr2,
                'isChange' => true
            ];
        } else {
            return [
                'org'      => $coArr1,
                'updated'  => $coArr2,
                'isChange' => false
            ];
        }
    }

    public static function getMappingData(
        $planeCad,
        $planePdf,
        $constructionCad,
        $constructionPdf,
        $effectImg,
        $softOutfitXlsx = []
    ) {
        $planeCadData[]        = [
            'type'     => OpenShopUploadFileResourceModel::FILE_TYPE_CAD,
            'position' => UploadFileResourceEnum::SPACE_DESIGN_CAD_PLANE,
            'url'      => getPrivateFileKey($planeCad)
        ];
        $planePdfData[]        = [
            'type'     => OpenShopUploadFileResourceModel::FILE_TYPE_PDF,
            'position' => UploadFileResourceEnum::SPACE_DESIGN_PDF_PLANE,
            'url'      => getPrivateFileKey($planePdf)
        ];
        $constructionCadData[] = [
            'type'     => OpenShopUploadFileResourceModel::FILE_TYPE_CAD,
            'position' => UploadFileResourceEnum::SPACE_DESIGN_CAD_CONSTRUCTION,
            'url'      => getPrivateFileKey($constructionCad)
        ];
        $constructionPdfData[] = [
            'type'     => OpenShopUploadFileResourceModel::FILE_TYPE_PDF,
            'position' => UploadFileResourceEnum::SPACE_DESIGN_PDF_CONSTRUCTION,
            'url'      => getPrivateFileKey($constructionPdf)
        ];
//        $softOutfitXlsxData[]  = [
//            'type'     => OpenShopUploadFileResourceModel::FILE_TYPE_XLSX,
//            'position' => UploadFileResourceEnum::SPACE_DESIGN_SOFT_XLSX,
//            'url'      => getPrivateFileKey($softOutfitXlsx)
//        ];
        $effectImg             = self::handleImg($effectImg, OpenShopUploadFileResourceModel::FILE_TYPE_IMG,
            UploadFileResourceEnum::SPACE_DESIGN_IMG);
        $mappingData           = [];
        $mappingData           = array_merge($mappingData, $planeCadData, $planePdfData, $constructionCadData,
            $constructionPdfData, $effectImg);
        return $mappingData;
    }

    public static function insertSpaceDesignCostData(
        $orderNo,
        $designFee,
        $merchantFee,
        $storeArea,
        $designArea,
        $overDesignFee = 0
    ) {
        try {
            DB::beginTransaction();
            $processAndAuthUser = self::getMainProcessAndAuthUser($orderNo);
            if (empty($processAndAuthUser)) {
                throw new ResponseHttpException(BaseErrorCode::$ORDER_NOT_EXIST);
            }

            // 没指定的时候，就用设计面积计算
            if (!$overDesignFee) {
                $overDesignArea = max($designArea - OpenShopSpaceDesignCostMappingModel::BASE_DESIGN_AREA, 0);
                $overDesignFee  = $overDesignArea * OpenShopSpaceDesignCostMappingModel::BASE_OVER_DESIGN_FEE * 100;
            } else {
                $overDesignArea = 0;
            }

            $totalFee = $designFee + $merchantFee + $overDesignFee;
            $rmsInfo  = getRmsUserInfoByAuth();
            $data     = [
                'orderNo'        => $orderNo,
                'preparationNo'  => self::genPreparationNo("CB"),
                'designFee'      => $designFee,
                'merchantFee'    => $merchantFee,
                'overDesignFee'  => $overDesignFee,
                'totalFee'       => $totalFee,
                'storeArea'      => $storeArea,
                'designArea'     => $designArea,
                'baseDesignArea' => OpenShopSpaceDesignCostMappingModel::BASE_DESIGN_AREA,
                'overDesignArea' => $overDesignArea,
                'createdAt'      => time(),
                'createdByUid'   => $rmsInfo->id,
                'updatedAt'      => time(),
                'updatedByUid'   => $rmsInfo->id,
            ];
            OpenShopSpaceDesignCostMappingModel::query()->insert($data);
            //修改主表状态
            OpenShopSpaceDesignModel::query()
                                    ->where('orderNo', $orderNo)
                                    ->update(['step' => MainProcessEnum::SPACE_DESIGN_STEP_TYPE_DESIGN_MODULE_PAY]);
            DB::commit();
            //任务 设计师确认设计模块
            event(new SignSiteMissionEvent($orderNo, MissionTemplateEnum::STEP_STATUS_13, $rmsInfo->id));
            event(new OpenShopProcessEvent($processAndAuthUser['rmsUser']->id,
                $processAndAuthUser['order']->mainProcessId, MainProcessEnum::MAIN_PROCESS_SPACE_DESIGN,
                MainProcessEnum::SPACE_DESIGN_STEP_TYPE_DESIGN_CONFIRM_DESIGN_MODULE));
            (new ShopTagsService($orderNo))->updateDesignPayTag();
        } catch (Exception $exception) {
            DB::rollBack();
            handleException($exception);
        }

    }

    public static function getSpaceDesignCostInfo($orderNo)
    {
        $designCostInfo = OpenShopSpaceDesignCostMappingModel::query()
                                                             ->where('orderNo', $orderNo)
                                                             ->first();
        if (!$designCostInfo) {
            return null;
        }
        return $designCostInfo->toArray();
    }


    /**
     * @return array|void
     * @throws Exception
     */
    public static function addCostOrderForm($cityCode)
    {
        try {
            $cityGradeFee            = OrderService::getOrderFeeFunc($cityCode);
            $result                  = ConfigService::config("openShop", "designOrderForm")["designOrderForm"];
            $result['merchantsLink'] = $cityGradeFee;
            return ["form" => $result];
        } catch (Exception $exception) {
            handleException($exception);
        }
    }


    public static function addCostOrder($orderNo, $overDesignArea, $designFee, $merchantFee, $uid)
    {
        $waitPay = OpenShopSpaceDesignCostMappingModel::waitPayCount($orderNo);
        if ($waitPay > 0) {
            \App\Service\BaseService::throwErr('已有待支付的设计订单，请删除后再添加');
        }

        try {
            DB::beginTransaction();
            $overDesignFee = $overDesignArea * OpenShopSpaceDesignCostMappingModel::BASE_OVER_DESIGN_FEE * 100;
            $data          = [
                'orderNo'        => $orderNo,
                'preparationNo'  => self::genPreparationNo("CB"),
                'overDesignArea' => $overDesignArea,
                'overDesignFee'  => $overDesignFee,
                'totalFee'       => $overDesignFee + $designFee + $merchantFee,
                'createdAt'      => time(),
                'createdByUid'   => $uid,
                'updatedAt'      => time(),
                'updatedByUid'   => $uid,
                'designFee'      => $designFee,
                'merchantFee'    => $merchantFee
            ];
            $id = OpenShopSpaceDesignCostMappingModel::query()
                                               ->insertGetId($data);
            //所有订单支付成功之后新增任务
            $siteMission = OpenShopSiteMissionModel::query()
                                                   ->where('orderNo', $orderNo)
                                                   ->where('stepStatus', MissionTemplateEnum::STEP_STATUS_14)
                                                   ->where('status', SiteMissionEnum::STATUS_1)
                                                   ->count();

            // 任务清空完了，才新增任务
            if (!$siteMission) {
                SiteMissionService::genMission($orderNo, MissionTemplateEnum::STEP_STATUS_14);
            }

            // 更新设计模块标签
            (new ShopTagsService($orderNo))->updateDesignPayTag();
            DB::commit();
            return $id;
        } catch (Exception $exception) {
            DB::rollBack();
            handleException($exception);
        }
    }

    public static function addSoftOrder($orderNo, $rmsInfo, array $equipments)
    {
        // 创建软装订单
        $body = DesignerEquipmentService::createNewOrder($orderNo, $equipments, $rmsInfo->username, CheckEnum::SYS_TYPE_OPEN_SHOP_DECORATE);
        $code = $body['code'] ?? -1;
        if (0 !== $code) {
            $msg = $body['msg'] ?? '创建软装订单失败';
            self::throwErr($msg);
        }
        $softOutfitFee = round( 100 * $body['data']['total_amount']);

        try {
            DB::beginTransaction();

            $softData = [
                'orderNo'       => $orderNo,
                'preparationNo' => self::genPreparationNo("CB"),
                'fileId'        => 0,
                'fee'           => $softOutfitFee,
                'createdAt'     => time(),
                'createdByUid'  => $rmsInfo->id,
                'updatedAt'     => time(),
                'updatedByUid'  => $rmsInfo->id,
                'newOrderCode' => $body['data']['code'] ?? '',
            ];
            //添加空间设计软装关联表
            SoftOutfitModel::query()
                           ->insert($softData);

            //所有订单支付成功之后新增任务
            $siteMission = OpenShopSiteMissionModel::query()
                                                   ->where('orderNo', $orderNo)
                                                   ->where('stepStatus', MissionTemplateEnum::STEP_STATUS_17)
                                                   ->where('status', SiteMissionEnum::STATUS_1)
                                                   ->count();

            if (!$siteMission) {
                // 直接insert任务软装待支付 MissionTemplateEnum::STEP_STATUS_8(整套图待提交)
                SiteMissionService::genMission($orderNo, MissionTemplateEnum::STEP_STATUS_17);
            }
            (new ShopTagsService($orderNo))->updateSoftPayTag();
            DB::commit();
        } catch (Exception $exception) {
            DB::rollBack();
            handleException($exception, BaseErrorCode::$ADD_ERROR_SOFT);
        }
    }

    public static function getCostOrderInfo($preparationNo)
    {
        //获取订单信息
        $info = OpenShopSpaceDesignCostMappingModel::query()
                                                   ->where('preparationNo', $preparationNo)
                                                   ->first();
        if (empty($info)) {
            return [];
        }

        $designOrderForm       = ConfigService::config("openShop", "designOrderForm")["designOrderForm"] ?? [];
        $excessiveDesignFeePer = $designOrderForm["excessiveDesignFeePer"] ?? 10000;

        $data = [];
        if ($info['designFee']) {
            $data[] = [
                'name'      => '设计费',
                'num'       => '1',
                'unit'      => '元',
                'fee'       => $info['designFee'],
                'refundFee' => $info['refundDesignFee'],
                'type'      => OpenShopPreparationOrderRefundModel::ORDER_TYPE_0
            ];
        }

        if ($info['overDesignFee']) {
            $data[] = [
                'name'      => '超标设计费',
                'num'       => $info['overDesignFee'] / $excessiveDesignFeePer,
                'unit'      => '平方',
                'fee'       => $info['overDesignFee'],
                'refundFee' => $info['refundOverDesignFee'],
                'type'      => OpenShopPreparationOrderRefundModel::ORDER_TYPE_4
            ];
        }

        if ($info['merchantFee']) {
            $data[] = [
                'name'      => '商户通',
                'num'       => '1',
                'unit'      => '元',
                'fee'       => $info['merchantFee'],
                'refundFee' => $info['refundMerchantFee'],
                'type'      => OpenShopPreparationOrderRefundModel::ORDER_TYPE_1
            ];
        }

        $info            = $info->toArray();
        $info['feeData'] = $data;
        return $info;
    }


    public static function getSoftOrderInfo($preparationNo)
    {
        //获取订单信息
        $info = SoftOutfitModel::query()
                               ->with([
                                   'fileRel' => function ($query) {
                                       $query->where('isDeleted', 0)
                                             ->where('position',
                                                 UploadFileResourceEnum::SPACE_DESIGN_SOFT_XLSX);
                                   }
                               ])
                               ->where('preparationNo', $preparationNo)
                               ->first();
        if (empty($info)) {
            return [];
        }
        $info            = $info->toArray();
        $softData        = [
            'name'      => '软装报价',
            'num'       => '1',
            'unit'      => '次',
            'fee'       => $info['fee'],
            'payFee'    => $info['payFee'],
            'refundFee' => $info['refundFee'],
            'type'      => OpenShopPreparationOrderRefundModel::ORDER_TYPE_2
        ];
        $data[]          = $softData;
        $info['list']    = $data;
        $info['fileRel'] = $info['file_rel'];
        unset($info['file_rel']);
        if (!empty($info['fileRel'])) {
            $info['fileRel']['url'] = privateFilePath($info['fileRel']['url']);
        }
        return $info;
    }

    /**
     * 关闭软装订单
     *
     * @param string $preparationNo
     * @throws Exception
     */
    public static function closeSoftOrder(string $preparationNo)
    {
        try {
            DB::beginTransaction();
            $softInfo = SoftOutfitModel::query()
                                       ->where('preparationNo', $preparationNo)
//                                       ->where('payStatus', OpenShopSpaceDesignCostMappingModel::ORDER_PAY_STATUS_0)
                                       ->first();
            if (empty($softInfo)) {
                throw new ResponseHttpException(BaseErrorCode::$ORDER_NOT_EXIST);
            }

            if ($softInfo->payStatus != OpenShopSpaceDesignCostMappingModel::ORDER_PAY_STATUS_0) {
                throw new ResponseHttpException(SpaceDesignErrorTrait::$ORDER_STATUS_NOT_SUPPORT_CLOSE);
            }

            $softInfo->orderStatus = SoftOutfitModel::ORDER_STATUS_3;
            $softInfo->save();

            // 关闭任务
            SiteMissionService::closePayCloseMission($softInfo->orderNo, MissionTemplateEnum::STEP_STATUS_17);
            (new ShopTagsService($softInfo->orderNo))->updateSoftPayTag();
            DB::commit();
        } catch (Exception $exception) {
            DB::rollBack();
            handleException($exception);
        }

    }

    public static function completeSoftOrder($preparationNo)
    {
        try {
            DB::beginTransaction();
            $softInfo = SoftOutfitModel::query()
                                       ->where('preparationNo', $preparationNo)
                                       ->whereIn('payStatus',
                                           [
                                               OpenShopSpaceDesignCostMappingModel::ORDER_PAY_STATUS_2,
                                               OpenShopSpaceDesignCostMappingModel::ORDER_PAY_STATUS_3
                                           ])
                                       ->where('orderStatus',
                                           OpenShopSpaceDesignCostMappingModel::ORDER_STATUS_1)
                                       ->first();
            if (empty($softInfo)) {
                throw new ResponseHttpException(BaseErrorCode::$ORDER_NOT_EXIST);
            }
            $softInfo->orderStatus = SoftOutfitModel::ORDER_STATUS_2;
            $softInfo->save();
            (new ShopTagsService($softInfo->orderNo))->updateSoftPayTag();
            DB::commit();
        } catch (Exception $exception) {
            DB::rollBack();
            handleException($exception);
        }

    }

    /**
     * 关闭设计订单
     *
     * @param string $preparationNo
     * @throws Exception
     */
    public static function closeCostOrder(string $preparationNo)
    {
        try {
            DB::beginTransaction();
            //查询订单信息
            $costInfo = OpenShopSpaceDesignCostMappingModel::query()
                                                           ->where('preparationNo', $preparationNo)
//                                                           ->where('payStatus',
//                                                               OpenShopSpaceDesignCostMappingModel::ORDER_PAY_STATUS_0)
                                                           ->first();

            if (empty($costInfo)) {
                throw new ResponseHttpException(BaseErrorCode::$ORDER_NOT_EXIST);
            }

            if ($costInfo->payStatus != OpenShopSpaceDesignCostMappingModel::ORDER_PAY_STATUS_0) {
                throw new ResponseHttpException(SpaceDesignErrorTrait::$ORDER_STATUS_NOT_SUPPORT_CLOSE);
            }

            $costInfo->orderStatus = OpenShopSpaceDesignCostMappingModel::ORDER_STATUS_3;
            $costInfo->save();

            $waitNum = OpenShopSpaceDesignCostMappingModel::waitPayCount($costInfo->orderNo);
            if ($waitNum <= 0) {

                // 关闭任务
                SiteMissionService::closePayCloseMission($costInfo->orderNo, MissionTemplateEnum::STEP_STATUS_14);
            }

            (new ShopTagsService($costInfo->orderNo))->updateDesignPayTag();
            DB::commit();
        } catch (Exception $exception) {
            DB::rollBack();
            handleException($exception);
        }

    }

    public static function completeCostOrder($preparationNo)
    {
        try {
            DB::beginTransaction();
            //查询订单信息
            $costInfo = OpenShopSpaceDesignCostMappingModel::query()
                                                           ->where('preparationNo', $preparationNo)
                                                           ->whereIn('payStatus',
                                                               [
                                                                   OpenShopSpaceDesignCostMappingModel::ORDER_PAY_STATUS_2,
                                                                   OpenShopSpaceDesignCostMappingModel::ORDER_PAY_STATUS_3
                                                               ])
                                                           ->where('orderStatus',
                                                               OpenShopSpaceDesignCostMappingModel::ORDER_STATUS_1)
                                                           ->first();
            if (empty($costInfo)) {
                throw new ResponseHttpException(BaseErrorCode::$ORDER_NOT_EXIST);
            }
            $costInfo->orderStatus = OpenShopSpaceDesignCostMappingModel::ORDER_STATUS_2;
            $costInfo->save();

            DB::commit();
        } catch (Exception $exception) {
            DB::rollBack();
            handleException($exception);
        }
    }

    public static function refundPreparationOrder($preparationNo, $type, $refundMoney, $remark)
    {
        switch ($type) {
            case OpenShopPreparationOrderRefundModel::ORDER_TYPE_0:
                //todo 设计费
                self::refundCostOrder($preparationNo, $refundMoney, $type, $remark);
                break;
            case OpenShopPreparationOrderRefundModel::ORDER_TYPE_1:
                //todo 商户通
                self::refundCostOrder($preparationNo, $refundMoney, $type, $remark);
                break;
            case OpenShopPreparationOrderRefundModel::ORDER_TYPE_2:
                //todo 软装报价
                self::refundSoftOrder($preparationNo, $refundMoney, $type, $remark);
                break;
            case OpenShopPreparationOrderRefundModel::ORDER_TYPE_3:
                //装修保证金
                self::refundRenovationFee($preparationNo, $type, $refundMoney, $remark);
                break;
            case OpenShopPreparationOrderRefundModel::ORDER_TYPE_4:
                //超标设计费
                self::refundCostOrder($preparationNo, $refundMoney, $type, $remark);
                break;
            default :
                break;
        }
    }

    public static function refundCostOrder($preparationNo, $refundMoney, $type, $remark)
    {
        try {
            DB::beginTransaction();
            //查询主表可退金额
            $costInfo = OpenShopSpaceDesignCostMappingModel::query()
                                                           ->where('preparationNo', $preparationNo)
                                                           ->whereIn('payStatus',
                                                               [
                                                                   OpenShopSpaceDesignCostMappingModel::ORDER_PAY_STATUS_2,
                                                                   OpenShopSpaceDesignCostMappingModel::ORDER_PAY_STATUS_3
                                                               ])
                                                           ->first();
            if (empty($costInfo)) {
                throw new ResponseHttpException(BaseErrorCode::$ORDER_NOT_EXIST);
            }
            if ($type == OpenShopPreparationOrderRefundModel::ORDER_TYPE_0) {
                //计算可退设计费
                $canRefundFee = $costInfo['designFee'] - $costInfo['refundDesignFee'];
                if ($refundMoney > $canRefundFee) {
                    throw new ResponseHttpException(BaseErrorCode::$ORDER_REFUND_MONEY_OVER);
                }
                $refundDesign              = $refundMoney + $costInfo['refundDesignFee'];
                $costInfo->refundDesignFee = $refundDesign;
            } elseif ($type == OpenShopPreparationOrderRefundModel::ORDER_TYPE_1) {
                //计算可退商户通
                $canRefundFee = $costInfo['merchantFee'] - $costInfo['refundMerchantFee'];
                if ($refundMoney > $canRefundFee) {
                    throw new ResponseHttpException(BaseErrorCode::$ORDER_REFUND_MONEY_OVER);
                }
                $refundMerchantFee           = $refundMoney + $costInfo['refundMerchantFee'];
                $costInfo->refundMerchantFee = $refundMerchantFee;
            } else {
                //计算超标设计费
                $canRefundFee = $costInfo['overDesignFee'] - $costInfo['refundOverDesignFee'];
                if ($refundMoney > $canRefundFee) {
                    throw new ResponseHttpException(BaseErrorCode::$ORDER_REFUND_MONEY_OVER);
                }
                $refundOverDesignFee           = $refundMoney + $costInfo['refundOverDesignFee'];
                $costInfo->refundOverDesignFee = $refundOverDesignFee;
            }
            //计算退款
            $totalRefund = $costInfo['refundOverDesignFee'] + $costInfo['refundMerchantFee'] + $costInfo['refundDesignFee'];
            if ($totalRefund > 0) {
                $payStatus           = ($totalRefund == $costInfo['totalFee']) ? 4 : 3;
                $costInfo->payStatus = $payStatus;
            }
            if ($totalRefund == $costInfo['totalFee']) {
                $costInfo->orderStatus = OpenShopSpaceDesignCostMappingModel::ORDER_STATUS_3;
            }
            $costInfo->save();
            //添加退款记录
            $rmsInfo = getRmsUserInfoByAuth();
            self::insertRefundData($rmsInfo, $costInfo['orderNo'], $preparationNo, $type, $refundMoney, $remark);
            DB::commit();
        } catch (Exception $exception) {
            DB::rollBack();
            handleException($exception);
        }
    }

    public static function refundSoftOrder($preparationNo, $refundMoney, $type, $remark)
    {
        try {
            DB::beginTransaction();
            $softInfo = SoftOutfitModel::query()
                                       ->where('preparationNo', $preparationNo)
                                       ->whereIn('payStatus',
                                           [
                                               OpenShopSpaceDesignCostMappingModel::ORDER_PAY_STATUS_2,
                                               OpenShopSpaceDesignCostMappingModel::ORDER_PAY_STATUS_3
                                           ])
                                       ->first();
            if (empty($softInfo)) {
                throw new ResponseHttpException(BaseErrorCode::$ORDER_NOT_EXIST);
            }
            $canRefund = $softInfo['fee'] - $softInfo['refundFee'];
            if ($refundMoney > $canRefund) {
                throw new ResponseHttpException(BaseErrorCode::$ORDER_REFUND_MONEY_OVER);
            }
            $refundFee = $softInfo['refundFee'] + $refundMoney;
            if ($refundFee > 0) {
                $payStatus           = ($refundFee == $softInfo['fee']) ? 4 : 3;
                $softInfo->payStatus = $payStatus;
            }
            if ($refundFee == $softInfo['fee']) {
                $softInfo->orderStatus = SoftOutfitModel::ORDER_STATUS_3;
            }
            $softInfo->refundFee = $refundFee;
            $softInfo->save();
            $rmsInfo = getRmsUserInfoByAuth();
            self::insertRefundData($rmsInfo, $softInfo['orderNo'], $preparationNo, $type, $refundMoney, $remark);
            DB::commit();
        } catch (Exception $exception) {
            DB::rollBack();
            handleException($exception);
        }

    }

    public static function refundRenovationFee($preparationNo, $type, $refundMoney, $remark)
    {
        try {
            DB::beginTransaction();
            $rmsInfo = getRmsUserInfoByAuth();
            //查询可退保证金
            $contract = OpenShopUserContractModel::query()
                                                 ->where('orderNo', $preparationNo)
                                                 ->first();
            if (empty($contract)) {
                throw new ResponseHttpException(BaseErrorCode::$ORDER_NOT_EXIST);
            }
            $refundFee = $refundMoney + $contract['refundDecorationDeposit'];
            if ($contract['decorationDeposit'] < $refundFee) {
                throw new ResponseHttpException(BaseErrorCode::$ORDER_REFUND_MONEY_OVER);
            }
            $contract->refundDecorationDeposit = $refundFee;
            $contract->save();
            self::insertRefundData($rmsInfo, $preparationNo, '', $type, $refundMoney, $remark);
            DB::commit();
        } catch (Exception $exception) {
            DB::rollBack();
            handleException($exception);
        }

    }

    public static function insertRefundData($rmsInfo, $orderNo, $preparationNo, $type, $refundMoney, $remark)
    {
        $refundData = [
            'orderNo'        => $orderNo,
            'preparationNo'  => $preparationNo,
            'refundSerialNo' => self::genPreparationNo("CBTK"),
            'money'          => $refundMoney,
            'type'           => $type,
            'refundType'     => OpenShopPreparationOrderRefundModel::ORDER_REFUND_TYPE_0,
            'remark'         => $remark,
            'status'         => OpenShopPreparationOrderRefundModel::ORDER_STATUS_1,
            'createdAt'      => time(),
            'createdByUid'   => $rmsInfo->id,
            'updatedAt'      => time(),
            'updatedByUid'   => $rmsInfo->id
        ];
        OpenShopPreparationOrderRefundModel::query()->insert($refundData);
    }


    /**
     * 生成orderNo
     * @return string
     */
    public static function genPreparationNo($key): string
    {
        return vsprintf("%s%s%s", [
            $key,
            date("Ymd", time()),
            str_pad(
                floor(microtime(true) * 1000) - strtotime(date('Y-m-d 00:00:00'), time()) * 1000,
                8,
                "0",
                STR_PAD_LEFT
            )
        ]);
    }

    public static function softSendProduct($params, $rmsInfo)
    {
        try {
            DB::beginTransaction();
            $mainInfo = SoftOutfitModel::query()
                                       ->where('preparationNo', $params['preparationNo'])
                                       ->whereIn('payStatus',
                                           [SoftOutfitModel::ORDER_PAY_STATUS_2, SoftOutfitModel::ORDER_PAY_STATUS_3])
                                       ->where('orderStatus', SoftOutfitModel::ORDER_STATUS_1)
                                       ->first();
            if (empty($mainInfo)) {
                throw new ResponseHttpException(BaseErrorCode::$SEND_ERROR_SOFT);
            }
            list($provinceCode, $cityCode, $areaCode) = $params['receiverCode'];
            unset($params['receiverCode']);
            $params['createdAt']    = time();
            $params['updatedAt']    = time();
            $params['createdByUid'] = $rmsInfo->id;
            $params['updatedByUid'] = $rmsInfo->id;
            $params['sendNo']       = self::genPreparationNo('CBFH');
            $params['provinceCode'] = $provinceCode;
            $params['cityCode']     = $cityCode;
            $params['areaCode']     = $areaCode;
            OpenShopSpaceDesignSoftLogisticsModel::query()
                                                 ->insert($params);

            (new ShopTagsService($mainInfo->orderNo))->updateSoftPayDelivery();

            DB::commit();
        } catch (Exception $exception) {
            DB::rollBack();
            handleException($exception);
        }
    }


    public static function getSoftSendList($preparationNo)
    {
        return OpenShopSpaceDesignSoftLogisticsModel::query()
                                                    ->where('preparationNo', $preparationNo)
                                                    ->get()->toArray();
    }

    public static function deleteSoftSendInfo($sendNo, $rmsInfo)
    {
        $updateData = [
            'isDeleted'    => 1,
            'updatedByUid' => $rmsInfo->id,
            'updatedAt'    => time()
        ];
        return OpenShopSpaceDesignSoftLogisticsModel::query()
                                                    ->where('sendNo', $sendNo)
                                                    ->update($updateData);
    }

    public static function getSoftSendListByOrderNo($orderNo)
    {
        return OpenShopSpaceDesignSoftLogisticsModel::query()
                                                    ->where('orderNo', $orderNo)
                                                    ->get()->toArray();
    }

    public static function getFileId($orderNo)
    {
        return OpenShopUploadFileResourceModel::query()
                                              ->where('orderNo', $orderNo)
                                              ->where('position',
                                                  UploadFileResourceEnum::SPACE_DESIGN_SOFT_XLSX)
                                              ->where('type', OpenShopUploadFileResourceModel::FILE_TYPE_XLSX)
                                              ->where('isDeleted', 0)
                                              ->value('id');
    }

    public static function saveDebugDesignPrice(string $orderNo): string
    {
        $shopCode = (int)OpenShopSignOrderModel::query()->where('orderNo', $orderNo)->value('shopCode');
        if ($shopCode < 9000) {
            throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null, "仅支持门店编号>9000的订单操作");
        }

        $order = OpenShopSpaceDesignCostMappingModel::query()
                                                    ->where('orderNo', $orderNo)
                                                    ->where('payStatus',
                                                        OpenShopSpaceDesignCostMappingModel::ORDER_PAY_STATUS_0)
                                                    ->orderByDesc('id')
                                                    ->first();
        if (!$order) {
            throw new ResponseHttpException(BaseErrorCode::$ERROR_OCCURRED, null, "不存在未支付的设计单");
        }

        $order->designFee   = 1;
        $order->merchantFee = 1;
        $order->totalFee    = 2;
        $order->save();

        return $order->preparationNo;
    }

    /**
     * 跳步骤
     * @param string $orderNo
     * @param int $stepStatus
     * @param string $remark
     * @param int $currentUid
     * @param int $currentUserName
     * @return void
     */
    public static function skipStep(string $orderNo, int $stepStatus, string $remark, object $user): void
    {
        $mainProcess = OpenShopMainProcessModel::query()->where('orderNo', $orderNo)->first();
        if (!$mainProcess) {
            self::throwErr("不存在的orderNo");
        }
        $signOrder = OpenShopSignOrderModel::query()->where('orderNo', $orderNo)->first();
        if (!$signOrder || $signOrder->status == SignOrderEnum::ORDER_STATUS_NO) {
            self::throwErr("订单不存在或已作废");
        }
        $shopCode = $signOrder->shopCode;

        // 筹备、设计顾问
        $managerUids = OpenShopOrderManagerModel::query()
                                                ->where('mainProcessId', $signOrder->mainProcessId)
                                                ->whereIn('type', [
                                                    OpenShopOrderManagerModel::MANAGER_TYPE_3,
                                                    OpenShopOrderManagerModel::MANAGER_TYPE_4
                                                ])
                                                ->pluck('managerUid')
                                                ->toArray();

        switch ($stepStatus) {

            // 设计
            // 如果当前设计订单已产生，并且是未支付的情况下，该张（会有多张可能）自动关闭。如果是部分支付，则无法跳流程。
            case MissionTemplateEnum::STEP_STATUS_15:
                if (!in_array($mainProcess->nowStepStatus,
                    [MissionTemplateEnum::STEP_STATUS_13, MissionTemplateEnum::STEP_STATUS_14])) {
                    self::throwErr("当前阶段，不允许跳过设计");
                }

                // 部分支付
                $partPay = OpenShopSpaceDesignCostMappingModel::query()
                                                              ->where('orderNo', $orderNo)
                                                              ->where('orderStatus',
                                                                  OpenShopSpaceDesignCostMappingModel::ORDER_STATUS_0)
                                                              ->where('payStatus',
                                                                  OpenShopSpaceDesignCostMappingModel::ORDER_PAY_STATUS_1)
                                                              ->count();
                if ($partPay) {
                    self::throwErr("订单已部分支付，无法跳过流程");
                }

                // 删除未支付的记录
//                $delRow = OpenShopSpaceDesignCostMappingModel::query()
//                                                             ->where('orderNo', $orderNo)
//                                                             ->where('orderStatus',
//                                                                 OpenShopSpaceDesignCostMappingModel::ORDER_STATUS_0)
//                                                             ->where('payStatus',
//                                                                 OpenShopSpaceDesignCostMappingModel::ORDER_PAY_STATUS_0)
//                                                             ->update(['isDeleted' => 1]);

                if ($mainProcess->nowStepStatus == MissionTemplateEnum::STEP_STATUS_14) {

                    // 插入1条金额都是0的空记录
                    // SkipStepMultiple::doStepSkip($orderNo, MissionTemplateEnum::STEP_STATUS_13, $user, true);
                }

                $title = '已跳过设计模块';
                $type  = OpenShopSignOrderLogModel::SKIP_STEP_DESIGN;
                break;

            // 设备
            // 如果当前设备订单已产生，并且是未支付的情况下，该张（会有多张可能）自动关闭。如果是部分支付，则无法跳流程。
            case MissionTemplateEnum::STEP_STATUS_8:
                if (!in_array($mainProcess->nowStepStatus,
                    [MissionTemplateEnum::STEP_STATUS_15, MissionTemplateEnum::STEP_STATUS_16])) {
                    self::throwErr("当前阶段，不允许跳过设备");
                }

                // kfos的订单状况
                $kfosOrders = collect(KfosService::equipmentDeliveryNotes($orderNo)['orders'] ?? []);
                $partPay    = $kfosOrders->where('paymentStatus', 5)->count();
                if ($partPay) {
                    self::throwErr("订单已部分支付，无法跳过流程");
                }

                // 未支付的订货单-关闭订单
//                $kfosOrders->where('paymentStatus', 1)->pluck('id')->each(function ($id) use ($user) {
//                    OrmNewOrderRemote::cancelNewOrder($id, $user->username);
//                });

                $title = '已跳过设备模块';
                $type  = OpenShopSignOrderLogModel::SKIP_STEP_EQUIPMENT;
                break;

            // 软装
            // 如果当前软装订单已产生，并且是未支付的情况下，该张（会有多张可能）自动关闭。如果是部分支付，则无法跳流程。
            case MissionTemplateEnum::STEP_STATUS_9:
                if (!in_array($mainProcess->nowStepStatus,
                    [MissionTemplateEnum::STEP_STATUS_8, MissionTemplateEnum::STEP_STATUS_17])) {
                    self::throwErr("当前阶段，不允许跳过软装");
                }

                // 部分支付
                $partPay = SoftOutfitModel::query()
                                          ->where('orderNo', $orderNo)
                                          ->where('orderStatus', SoftOutfitModel::ORDER_STATUS_0)
                                          ->where('payStatus', SoftOutfitModel::ORDER_PAY_STATUS_1)
                                          ->count();
                if ($partPay) {
                    self::throwErr("订单已部分支付，无法跳过流程");
                }

                // 删除未支付的记录
//                $delRow = SoftOutfitModel::query()
//                                         ->where('orderNo', $orderNo)
//                                         ->where('orderStatus', SoftOutfitModel::ORDER_STATUS_0)
//                                         ->where('payStatus', SoftOutfitModel::ORDER_PAY_STATUS_0)
//                                         ->update(['isDeleted' => 1]);

                if ($mainProcess->nowStepStatus == MissionTemplateEnum::STEP_STATUS_17) {

                    // 插入1条金额都是0的空记录
                    // SkipStepMultiple::doStepSkip($orderNo, MissionTemplateEnum::STEP_STATUS_8, $user, true);
                }

                $title = '已跳过软装模块';
                $type  = OpenShopSignOrderLogModel::SKIP_STEP_DECORATE;
                break;

            default:
                self::throwErr("不支持其他阶段的跳过");
        }

        // 执行底层的步骤跳转
        SkipStepMultiple::doStepSkip($orderNo, $stepStatus, $user);

        // 订单日志
        $changes = json_encode([
            [
                "theme"      => mb_substr($title, 1, mb_strlen($title) - 1),
                "changeType" => ChangeSupport::CHANGE_TYPE_SINGLE_INSERT,
                "data"       => [
                    [
                        "key"         => "text",
                        "beforeValue" => $mainProcess->nowStepStatus,
                        "afterValue"  => $stepStatus,
                        "beforeText"  => MissionTemplateEnum::STEP_STATUS_TEXT[$mainProcess->nowStepStatus] ?? '',
                        "afterText"   => MissionTemplateEnum::STEP_STATUS_TEXT[$stepStatus] ?? '',
                        "type"        => ChangeSupport::FILED_TYPE_STRING,
                        "description" => $remark
                    ]
                ]
            ]
        ], JSON_UNESCAPED_UNICODE);
        OpenShopSignOrderLogModel::logInsert(
            OpenShopSignOrderModel::query()->where("orderNo", $orderNo)->first()->id,
            $type,
            $user->username,
            $user->id,
            $changes
        );

        // 通知
        $url = \App\Service\OpenShop\Feishu\BaseService::pcUrl("openShop/order/info/{$orderNo}?tab=process");
        (new FsCardService())
            ->buildElementField("**开店订单号：**\n{$orderNo}")
            ->buildElementField("**门店编号：**\n{$shopCode}")
            ->buildElementField("")
            ->buildElementField("")
            ->buildElementField("**处理角色：**\n员工")
            ->buildElementField("**处理人：**\n{$user->username}")
            ->buildElementField("")
            ->buildElementField("")
            ->buildElementField("**处理时间：**\n" . date('Y-m-d H:i:s'))
            ->buildElementField("")
            ->setKfUserIds($managerUids)
            ->setModule(UserPermissionAuth::MODULE_OPEN_SHOP)
            ->send([$title, $url]);

        if ($stepStatus == MissionTemplateEnum::STEP_STATUS_9) { // 筹备阶段-在 软装费 跳过此流程 之后，进行推送 评价消息
            NotifyService::notify($orderNo, AppraiseModel::TYPE_APP_SHOP_DESIGN, 0, $mainProcess->shopId);
        }
    }
}
